import dayjs from "dayjs";
import { PlatformUserAccountExpiredError } from "../../errors";
import { generateRandom } from "../../helper";
import { Client } from "./client";

export class Application {
  constructor(accountUser) {
    this.accountUser = accountUser;
    this.client = new Client(accountUser);
  }

  setRequest(request){
    this.client.setRequest(request)
  }

  // 获取账号信息
  async getUserAccount() {
    let response

    try {
      response = await this.client.getUserInfo();
    } catch (error) {
      console.log('douyin application getUserAccount error', error)

      throw new PlatformUserAccountExpiredError('账号已过期')
    }

    if(response.data.status_code != 0){
      throw new PlatformUserAccountExpiredError(response.data.status_msg)
    }

    return response.data.user
  }

  // 发布视频
  async syncVideoRelease(filmRelease) {
    const title = filmRelease.title || '';
    const desc = filmRelease.caption || '';
    const videoUrl = filmRelease.multimedia?.material_url;
    const hashtag_name = filmRelease.hashtag_name || [];
    const visibility_type = Number(filmRelease.visibility_type);
    const download = Number(filmRelease.download);
    const poi_id = filmRelease.associ_poi?.poi_id || '';
    const poi_name = filmRelease.associ_poi?.store_name || '';
    const anchor = filmRelease.anchor || {};
    const titleLength = title.length;
    const textExtra = [];

    // 定时发布
    const extraInfo = filmRelease.extra_info || {};

    const sendTime = extraInfo.sendTime || 0;
    let timeOut = extraInfo.timeOut || 0;

    if (! videoUrl){
      throw new Error('视频地址不能为空')
    }

    let caption = desc;
    let challengeNames = '';
    let processedDesc = desc.replace(/<[^>]*>/g, '');

    if (title) {
      processedDesc = `${title} ${processedDesc}`;
    }

    const challenges = await Promise.all((hashtag_name).map(challenge => this.searchChallengeSug(challenge)));

    let captionEnd = processedDesc.length;

    for (const challenge of challenges) {
      const hashtagText = `#${challenge.hashtag_name}`;
      const end = captionEnd + hashtagText.length;
      
      textExtra.push({
        start: captionEnd,
        end: end,
        type: 1,
        hashtag_name: challenge.hashtag_name,
        hashtag_id: Number(challenge.hashtag_id || 0),
        user_id: '',
        caption_start: captionEnd - titleLength - 1,
        caption_end: end - titleLength - 1
      });

      captionEnd = end + 1;
    }

    if (challenges.length) {
      challengeNames = challenges.map(challenge => `#${challenge.hashtag_name}`);
    }

    let hashtag_source = '';
    if (challengeNames.length) {
      processedDesc += ' ' + challengeNames.join(' ');
      caption += ' ' + challengeNames.join(' ');
      hashtag_source = 'recommend/recommend';
    }

    const [ uploadVideoRes = null ] = await this.client.uploadVideo(videoUrl);

    if(! uploadVideoRes){
      throw new Error('视频上传失败')
    }

    const videoId = uploadVideoRes.videoId;
    const creation_times = Math.round(Date.now());
    const creation_id = generateRandom(8).toLowerCase() + creation_times;
    const poi_component = anchor.poi_component || {};
    const poi_id_good = poi_component.poi_id || '';
    const poi_name_good = poi_component.poi_name || '';
    const poi_anchor_content = poi_component.anchor_content || [];

    const versionData = {};
    const itemData = {};
    const commonData = {
      text: processedDesc.trim(),
      caption: caption.trim(),
      item_title: title.trim(),
      activity: '[]',
      text_extra: textExtra.length ? JSON.stringify(textExtra) : '[]',
      challenges: '[]',
      mentions: '[]',
      hashtag_source: hashtag_source || '',
      hot_sentence: '',
      download,
      visibility_type,
      timing: 0,
      creation_id,
      media_type: 4,
      video_id: videoId,
      music_source: 0,
      music_id: null,
      source_info: '{}'
    };

    // 避免溢出 超过14天 或者 时间不足2小时
    if (timeOut > 0 && timeOut > 7200) {
      timeOut -= 10;
    }
    if (timeOut > 0 && timeOut < 7200 + 10) {
      timeOut = 7200 + 30;
    }
    if (timeOut > 0 && timeOut > 1209600) {
      timeOut = 1209600 - 10;
    }

    if (timeOut > 0) {
      const delayLowTime = dayjs().unix() + 6800;
      if (sendTime > 0 && sendTime < delayLowTime) {
        // 如果存在延迟发布时间 且延迟时间已经不足2小时 默认2小时后发布 否则会报错
        commonData.timing = delayLowTime;
      } else if (sendTime > delayLowTime) {
        // 如果存在延迟发布时间 且延迟时间超过1小时 直接使用延迟时间发布
        commonData.timing = sendTime;
      } else {
        const timing = dayjs().unix() + timeOut;
        commonData.timing = timing;
      }
    }

    const anchorData = {};
    let applet_id = '';

    if (poi_id_good) {
      applet_id = poi_id_good;
      anchorData.poi_id = poi_id_good;
      anchorData.poi_name = poi_name_good;
      anchorData.anchor_content = JSON.stringify(
        poi_anchor_content || {
          is_commerce_intention: true,
          recommend_poi_group: true,
          primary_recommend_product_type: 1
        }
      );
    } else if (poi_id) {
      applet_id = poi_id;

      anchorData.poi_id = poi_id;
      anchorData.poi_name = poi_name;
      anchorData.anchor_content = JSON.stringify({
        is_commerce_intention: true,
        recommend_poi_group: true,
        primary_recommend_product_type: 1
      });
    } else if (anchor.mini_program) {
      anchorData = anchor.mini_program;
    }

    if (anchor.shop_cart?.shop_draft_id) {
      anchorData.shop_draft_id = anchor.shop_cart.shop_draft_id;
    }

    if (applet_id) {
      try {
        const poiAuthResult = await this.client.lifeVideoApiPostPermission({
          from_webapp: 1,
          is_image_album_style: 0
        });

        const has_promote_auth = poiAuthResult.has_promote_auth || false;
        if (!has_promote_auth) {
          delete anchorData.anchor_content;
          applet_id = '';
        }
      } catch (error) {
        console.error('检查带货权限失败:', error);
      }
    }

    itemData.common = commonData;
    itemData.anchor = Object.keys(anchorData).length ? anchorData : {};
    itemData.mix = {};
    itemData.sync = {
      should_sync: false,
      sync_to_toutiao: 0
    };
    itemData.open_platform = {};
    itemData.assistant = {
      is_preview: 0,
      is_post_assistant: 1
    };
    itemData.declare = {
      user_declare_info: '{}'
    };

    versionData.item = itemData;

    if(applet_id){
      await this.client.userAnchorCheck({
        applet_id,
        item_type: 1,
        select_anchor: 2,
      })
    }

    const result = await this.client.getPublicVideoV2(versionData);
    result['success'] = true;

    return result
  }

  // 搜索话题
  async searchChallengeSug(challenge) {
    let response = await this.client.searchChallengeSug(challenge)

    return {
      hashtag_name: challenge,
      hashtag_id: (response?.sug_list?.[0]?.cid || '').toString(),
    }
  }
}